//
//  Account.m
//  thread
//
//  Created by 关旭 on 2019/3/8.
//  Copyright © 2019 guanxu. All rights reserved.
//

#import "Account.h"

@interface Account()
{
    
}
@property (nonatomic,strong)NSLock *lock;
@end
@implementation Account

- (instancetype )init {
    self = [super init];
    if (self) {
        self.lock = [[NSLock alloc]init];
    }
    return self;
}


- (void)draw:(id)money
{
//    当多个线程同时操作的时候，会存在竞争条件，数据结果就无法保证
//    double drawMoney = [money doubleValue];
//    //判断余额是否足够
//    if (self.balance >= drawMoney)
//    {
//        //当前线程睡1毫秒
//        [NSThread sleepForTimeInterval:0.001];
//        self.balance -= drawMoney;
//        NSLog(@"%@ draw money %lf balance left %lf", [[NSThread currentThread] name], drawMoney, self.balance);
//    }else{
//        //余额不足，提示
//        NSLog(@"%@ Balance Not Enouth", [[NSThread currentThread] name]);
//    }
    
    
//    我们对draw:方法添加了一个同步代码块，使用@synchronized包围的代码即为同步代码块，同步代码块需要一个监听器，我们使用account对象本身作为监听器，因为是account对象产生的竞争条件，当执行同步代码块时需要先获取监听器，如果获取不到则线程会被阻塞，当同步代码块执行完成则释放监听器
//    @synchronized (self) {
//        double drawMoney = [money doubleValue];
//        if (self.balance >= drawMoney)
//        {
//            //当前线程睡1毫秒
//            [NSThread sleepForTimeInterval:1];
//            self.balance -= drawMoney;
//            NSLog(@"%@ draw money %lf balance left %lf", [[NSThread currentThread] name], drawMoney, self.balance);
//        }else{
//            //余额不足，提示
//            NSLog(@"%@ Balance Not Enouth", [[NSThread currentThread] name]);
//        }
//    }
    
    
    
//    我们使用锁机制，创建了一个NSLock类的锁对象，lock方法用于获取锁，如果锁被其他对象占用则线程被阻塞，unlock方法用于释放锁，以便其他线程加锁。
    [self.lock lock];
    double drawMoney = [money doubleValue];
    if (self.balance >= drawMoney)
    {
        //当前线程睡1毫秒
        [NSThread sleepForTimeInterval:1];
        self.balance -= drawMoney;
        NSLog(@"%@ draw money %lf balance left %lf", [[NSThread currentThread] name], drawMoney, self.balance);
    }else{
        //余额不足，提示
        NSLog(@"%@ Balance Not Enouth", [[NSThread currentThread] name]);
    }
    [self.lock unlock];
}

@end
